package org.opens.util;

import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.flowable.task.api.Task;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class FlowableUtil {

    private static ProcessEngine PROCESS_ENGINE = null;

    public static ProcessEngine getProcessEngine() {
        if (PROCESS_ENGINE != null) {
            return PROCESS_ENGINE;
        }

        // 安全保护
        synchronized (FlowableUtil.class) {
            if (PROCESS_ENGINE != null) {
                return PROCESS_ENGINE;
            }
            initProcessEngine();
            return PROCESS_ENGINE;
        }

    }

    /**
     * 根据流程对应的key查询流程相关信息
     * @param key   流程定义key
     */
    public static void showProcessInfoByKey(String key) {
        ProcessEngine processEngine = FlowableUtil.getProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 获取查询对象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();

        // 设置查询条件
        ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionKey(key).singleResult();

        System.out.println("processDefinition.getDeploymentId() = " + processDefinition.getDeploymentId());
        System.out.println("processDefinition.getName() = " + processDefinition.getName());
        System.out.println("processDefinition.getDescription() = " + processDefinition.getDescription());
        System.out.println("processDefinition.getId() = " + processDefinition.getId());
        System.out.println("processDefinition.getKey() = " + processDefinition.getKey());
    }

    private static void initProcessEngine() {
        // 获取ProcessEngineConfiguration对象
        ProcessEngineConfiguration configuration = new StandaloneProcessEngineConfiguration();

        // 配置数据库相关的连接信息
        configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");
        configuration.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/flowable20240311?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false&nullCatalogMeansCurrent=true");
        configuration.setJdbcUsername("root");
        configuration.setJdbcPassword("qq991264921");
        // 如果数据库中的表结构不存在则创建
        configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

        // 通过ProcessEngineConfiguration构建我们需要的ProcessEngine对象
        PROCESS_ENGINE = configuration.buildProcessEngine();
    }

    public static void loadXml(String xmlFilePath, String flowName) {
        ProcessEngine processEngine = FlowableUtil.getProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deployment = repositoryService.createDeployment()
                // 关联要部署的流程文件
                .addClasspathResource(xmlFilePath)
                // 这个名称会最终设置到act_re_deployment表的name_字段
                .name(flowName)
                // 部署流程
                .deploy();
        System.out.println("流程id: " + deployment.getId());
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId())
                .singleResult();
        System.out.println("processDefinition.getName() = " + processDefinition.getName());
        System.out.println("processDefinition.getId() = " + processDefinition.getId());
    }

    public static void showVariablesMap(Map<String, Object> processVariables) {
        Iterator<Map.Entry<String, Object>> iterator = processVariables.entrySet().iterator();
        System.out.println("---流程变量打印start, size=" + processVariables.size() + "---");
        while (iterator.hasNext()) {
            Map.Entry<String, Object> next = iterator.next();
            System.out.println(next.getKey() + ": " + next.getValue());
        }
        System.out.println("---流程变量打印end---");
    }

}
